home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
TECHFUN.ZIP
/
XMODE.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-05-23
|
38KB
|
1,422 lines
.MODEL HUGE, C
.486
.CODE
; XMODE routines by Kaos (a.k.a. Bruno Carlos) of Black Magic
; Mode 0 -> 320x200 4 pages
; Mode 1 -> 320x240 3 pages
; Mode 2 -> 320x400 2 pages
; Mode 3 -> 320x480 1 page
; Mode 4 -> 360x200 3 pages
; Mode 5 -> 360x240 3 pages
; Mode 6 -> 360x400 1 page
; Mode 7 -> 360x480 1 page
; If you use this code in any of your
; productions give us the proper credits...
;****************************************************************************
out_16 MACRO register, value
ifdifi <register>,<dx> ; if dx not setup
mov dx,register ; then select register
endif
ifdifi <value>,<ax> ; if ax not setup
mov ax,value ; then get data value
endif
out dx,ax ; set i/o register(s)
ENDM
;****************************************************************************
out_8 MACRO register, value
ifdifi <register>,<dx> ; if dx not setup
mov dx,register ; then select register
endif
ifdifi <value>,<al> ; if al not setup
mov al,value ; then get data value
endif
out dx,al ; set i/o register
ENDM
;******************************************************************************
vwait MACRO
local Vertout,Vertin
mov dx,03DAh
Vertout:
in al,dx
test al,8
jnz Vertout ; wait Until out of vertical retrace
Vertin:
in al,dx
test al,8
jz Vertin ; wait Until inside vertical retrace
ENDM
;******************************************************************************
hwait MACRO
local Horzout,Horzin
mov dx,03DAh
Horzout:
in al,dx
test al,1
jnz Horzout ; wait Until out of horizontal retrace
Horzin:
in al,dx
test al,1
jz Horzin ; wait Until inside horizontal retrace
ENDM
;****************************************************************************
xmode:
dw offset X320x200
dw offset X320x240
dw offset X320x400
dw offset X320x480
dw offset X360x200
dw offset X360x240
dw offset X360x400
dw offset X360x480
;****************************************************************************
X320x200:
db 063h ; 400 scan lines & 25 mhz clock
dw 05f00h ; horz total
dw 04f01h ; horz displayed
dw 05002h ; start horz blanking
dw 08203h ; end horz blanking
dw 05404h ; start h sync
dw 08005h ; end h sync
dw 0bf06h ; vertical total
dw 01f07h ; overflow
dw 09c10h ; v sync start
dw 08e11h ; v sync end/prot cr0 cr7
dw 08f12h ; vertical displayed
dw 09615h ; v blank start
dw 0b916h ; v blank end
dw 04109h ; cell height (2 scan lines)
dw 00014h ; dword mode off
dw 0e317h ; turn on byte mode
dw 16000/4 ; page size (dwords)
dw 320 ; xmax
dw 200 ; ymax
dw 0 ; page 1 offset
dw 16000 ; page 2 offset
dw 32000 ; page 3 offset
dw 48000 ; page 4 offset
;****************************************************************************
X320x240:
db 0e3h ; 480 scan lines & 25 mhz clock
dw 05f00h ; horz total
dw 04f01h ; horz displayed
dw 05002h ; start horz blanking
dw 08203h ; end horz blanking
dw 05404h ; start h sync
dw 08005h ; end h sync
dw 00d06h ; vertical total
dw 03e07h ; overflow
dw 0ea10h ; v sync start
dw 08c11h ; v sync end/prot cr0 cr7
dw 0df12h ; vertical displayed
dw 0e715h ; v blank start
dw 00616h ; v blank end
dw 04109h ; cell height (2 scan lines)
dw 00014h ; dword mode off
dw 0e317h ; turn on byte mode
dw 19200/4 ; page size (dwords)
dw 320 ; xmax
dw 240 ; ymax
dw 0 ; page 1 offset
dw 19200 ; page 2 offset
dw 38400 ; page 3 offset
dw 0 ; page 4 offset (same as page 1)
;****************************************************************************
X320x400:
db 063h ; 400 scan lines & 25 mhz clock
dw 05f00h ; horz total
dw 04f01h ; horz displayed
dw 05002h ; start horz blanking
dw 08203h ; end horz blanking
dw 05404h ; start h sync
dw 08005h ; end h sync
dw 0bf06h ; vertical total
dw 01f07h ; overflow
dw 09c10h ; v sync start
dw 08e11h ; v sync end/prot cr0 cr7
dw 08f12h ; vertical displayed
dw 09615h ; v blank start
dw 0b916h ; v blank end
dw 04009h ; cell height (1 scan line)
dw 00014h ; dword mode off
dw 0e317h ; turn on byte mode
dw 32000/4 ; page size (dwords)
dw 320 ; xmax
dw 400 ; ymax
dw 0 ; page 1 offset
dw 32000 ; page 2 offset
dw 0 ; page 3 offset (same as page 1)
dw 32000 ; page 4 offset (same as page 2)
;****************************************************************************
X320x480:
db 0e3h ; 480 scan lines & 25 mhz clock
dw 05f00h ; horz total
dw 04f01h ; horz displayed
dw 05002h ; start horz blanking
dw 08203h ; end horz blanking
dw 05404h ; start h sync
dw 08005h ; end h sync
dw 00d06h ; vertical total
dw 03e07h ; overflow
dw 0ea10h ; v sync start
dw 08c11h ; v sync end/prot cr0 cr7
dw 0df12h ; vertical displayed
dw 0e715h ; v blank start
dw 00616h ; v blank end
dw 04009h ; cell height (1 scan line)
dw 00014h ; dword mode off
dw 0e317h ; turn on byte mode
dw 38400/4 ; page size (dwords)
dw 320 ; xmax
dw 480 ; ymax
dw 0 ; page 1 offset
dw 0 ; page 2 offset (same as page 1)
dw 0 ; page 3 offset (same as page 1)
dw 0 ; page 4 offset (same as page 1)
;****************************************************************************
X360x200:
db 067h ; 400 scan lines & 28 mhz clock
dw 06b00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08e03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 0bf06h ; vertical total
dw 01f07h ; overflow
dw 09c10h ; v sync start
dw 08e11h ; v sync end/prot cr0 cr7
dw 08f12h ; vertical displayed
dw 09615h ; v blank start
dw 0b916h ; v blank end
dw 04109h ; cell height (2 scan lines)
dw 00014h ; dword mode off
dw 0e317h ; turn on byte mode
dw 18000/4 ; page size (dwords)
dw 360 ; xmax
dw 200 ; ymax
dw 0 ; page 1 offset
dw 18000 ; page 2 offset
dw 36000 ; page 3 offset
dw 0 ; page 4 offset (same as page 1)
;****************************************************************************
X360x240:
db 0e7h ; 480 scan lines & 28 mhz clock
dw 06b00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08e03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 00d06h ; vertical total
dw 03e07h ; overflow
dw 0ea10h ; v sync start
dw 08c11h ; v sync end/prot cr0 cr7
dw 0df12h ; vertical displayed
dw 0e715h ; v blank start
dw 00616h ; v blank end
dw 04109h ; cell height (2 scan lines)
dw 00014h ; dword mode off
dw 0e317h ; turn on byte mode
dw 21600/4 ; page size (dwords)
dw 360 ; xmax
dw 240 ; ymax
dw 0 ; page 1 offset
dw 21600 ; page 2 offset
dw 43200 ; page 3 offset
dw 0 ; page 4 offset (same as page 1)
;****************************************************************************
X360x400:
db 067h ; 400 scan lines & 28 mhz clock
dw 06b00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08e03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 0bf06h ; vertical total
dw 01f07h ; overflow
dw 09c10h ; v sync start
dw 08e11h ; v sync end/prot cr0 cr7
dw 08f12h ; vertical displayed
dw 09615h ; v blank start
dw 0b916h ; v blank end
dw 04009h ; cell height (1 scan line)
dw 00014h ; dword mode off
dw 0e317h ; turn on byte mode
dw 36000/4 ; page size (dwords)
dw 360 ; xmax
dw 400 ; ymax
dw 0 ; page 1 offset
dw 0 ; page 2 offset (same as page 1)
dw 0 ; page 3 offset (same as page 1)
dw 0 ; page 4 offset (same as page 1)
;****************************************************************************
X360x480:
db 0e7h ; 480 scan lines & 28 mhz clock
dw 06b00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08e03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 00d06h ; vertical total
dw 03e07h ; overflow
dw 0ea10h ; v sync start
dw 08c11h ; v sync end/prot cr0 cr7
dw 0df12h ; vertical displayed
dw 0e715h ; v blank start
dw 00616h ; v blank end
dw 04009h ; cell height (1 scan line)
dw 00014h ; dword mode off
dw 0e317h ; turn on byte mode
dw 43200/4 ; page size (dwords)
dw 360 ; xmax
dw 480 ; ymax
dw 0 ; page 1 offset
dw 0 ; page 2 offset (same as page 1)
dw 0 ; page 3 offset (same as page 1)
dw 0 ; page 4 offset (same as page 1)
;****************************************************************************
attrib_ctrl equ 03c0h ; vga attribute controller
gc_index equ 03ceh ; vga graphics controller
sc_index equ 03c4h ; vga sequencer controller
sc_data equ 03c5h ; vga sequencer data port
crtc_index equ 03d4h ; vga crt controller
crtc_data equ 03d5h ; vga crt controller data
misc_output equ 03c2h ; vga misc register
input_1 equ 03dah ; input status #1 register
dac_write_addr equ 03c8h ; vga dac write addr register
dac_read_addr equ 03c7h ; vga dac read addr register
pel_data_reg equ 03c9h ; vga dac/pel data register r/w
pixel_pan_reg equ 033h ; attrib index: pixel pan reg
map_mask equ 002h ; sequ index: write map mask reg
read_map equ 004h ; gc index: read map register
start_disp_hi equ 00ch ; crtc index: display start hi
start_disp_lo equ 00dh ; crtc index: display start lo
map_mask_plane1 equ 00102h ; map register + plane 1
map_mask_plane2 equ 01102h ; map register + plane 1
all_planes_on equ 00f02h ; map register + all bit planes
chain4_off equ 00604h ; chain 4 mode off
async_reset equ 00100h ; (a)synchronous reset
sequ_restart equ 00300h ; sequencer restart
latches_on equ 00008h ; bit mask + data from latches
latches_off equ 0ff08h ; bit mask + data from cpu
vert_retrace equ 08h ; input_1: vertical retrace bit
plane_bits equ 03h ; bits 0-1 of xpos = plane #
all_planes equ 0fh ; all bit planes selected
char_bits equ 0fh ; bits 0-3 of character data
;****************************************************************************
PUBLIC rows
PUBLIC pages
PUBLIC xmax
PUBLIC ymax
PUBLIC vxmin
PUBLIC vymin
PUBLIC vxmax
PUBLIC vymax
;****************************************************************************
rows dw 800 dup(0) ; addresses to all rows in the screen
pages dw 4 dup(0) ; offsets of all video pages
scr_width dw ? ; screen width in pixels
pagesize dw ?
xmax dw ?
ymax dw ?
vxmin dw ?
vymin dw ?
vxmax dw ?
vymax dw ?
;****************************************************************************
PUBLIC xinitvideo
xinitvideo PROC mode:word
push ds
push es
push si
push di
and mode,00000111b ; make sure mode is in range 0->7
cli
vwait ; wait for start of vertical retrace
mov dx,3c8h ; clear palette to remove flicker
xor al,al
out dx,al
inc dx
mov cx,768
xcp1:
out dx,al
loop xcp1
vwait
sti
mov ax,0013h ; set normal 320x200 graphics mode
int 10h
cli
mov dx,3c8h ; clear palette again
xor al,al
out dx,al
inc dx
mov cx,768
xcp2:
out dx,al
loop xcp2
vwait
out_16 sc_index,chain4_off ; disable chain 4 mode
out_16 sc_index,async_reset ; (a)synchronous reset
mov bx,mode ; get xmode
shl bx,1 ; multiply it by 2
mov si,word ptr xmode[bx] ; point to Xmode table
mov al,byte ptr cs:[si] ; get crtc data from table
out_8 misc_output,al ; set new timing/size
out_16 sc_index,sequ_restart ; restart sequencer ...
out_8 crtc_index,11h ; select vert retrace end register
inc dx ; point to data
in al,dx ; get value, bit 7 = protect
and al,7fh ; mask out write protect
out dx,al ; and send it back
mov dx,crtc_index ; vga crtc registers
add si,1 ; advance pointer
mov cx,16 ; we are going to send out 16 words
xiv1:
mov ax,word ptr cs:[si] ; get crtc data from table
add si,2 ; advance pointer
out dx,ax ; reprogram vga crtc reg
loop xiv1 ; do it 16 times
mov ax,word ptr cs:[si] ; get pagesize from table
mov pagesize,ax ; update pagesize var
mov ax,word ptr cs:[si+2] ; get xmax from table
mov xmax,ax ; update xmax var
mov vxmax,ax
mov ax,word ptr cs:[si+4] ; get ymax from table
mov ymax,ax ; update ymax var
mov vymax,ax
mov ax,xmax ; get xmax
shr ax, 2 ; bytes = pixels / 4
mov scr_width, ax ; save width in bytes
shr ax,1 ; offset value = bytes / 2
mov ah,13h ; crtc offset register index
xchg al,ah ; switch format for out
out dx,ax ; set vga crtc offset reg
mov cx,800 ; get # of rows
mov bx,offset rows ; point to rows table
xor ax,ax ; clear ax
xiv2:
mov cs:[bx],ax ; put row offset in table
add ax,scr_width ; get next row offset
add bx,2 ; advance pointer
loop xiv2 ; loop until i'ts done
mov ax,cs ; get code segment
mov ds,ax ; load ds with it
mov es,ax ; and es too
mov cx,4 ; cx=counter=4
add si,6 ; point si to xmode specific pages
mov di,offset pages ; point di to pages table
rep movsw ; move 4 words from ds:si to es:di
mov vxmin,0
mov vymin,0
sti
pop di
pop si
pop es
pop ds
ret
xinitvideo ENDP
;****************************************************************************
PUBLIC xclrvram
xclrvram PROC
push es
push di
mov dx,003c4h ; update all 4 bit-planes at the same time
mov ax,00f02h
out dx,ax
cld ; block fill forwards
mov ax,0a000h ; clear vram (all planes)
mov es,ax
xor di,di
mov cx,16384
xor eax,eax
rep stosd
pop di
pop es
ret
xclrvram ENDP
;****************************************************************************
PUBLIC xclrvpage
xclrvpage PROC vpage:word
push es
push di
mov ax,0a000h
mov es,ax ; point to vga memory segment
mov bx,vpage ; get page #
and bx,00000011b ; make sure page # is in range 0->3
shl bx,1 ; scale bx
mov di,cs:pages[bx] ; get page offset
out_16 sc_index,all_planes_on ; select all planes
xor eax,eax ; fill page with color 0
cld ; block fill forwards
mov cx,pagesize ; get size of page
rep stosd ; block fill vga memory
pop di
pop es
ret
xclrvpage ENDP
;****************************************************************************
PUBLIC xsetvpage
xsetvpage PROC vpage:word
mov bx,vpage ; get page #
and bx,00000011b ; make sure page # is in range 0->3
shl bx,1 ; scale bx
mov bx,cs:pages[bx] ; get page offset
mov dx,03d4h ; we change the vga sequencer
mov al,00ch ; display start high register
mov ah,bh ; high 8 bits of start addr
out dx,ax ; set display addr high
mov al,00dh ; display start low register
mov ah,bl ; low 8 bits of start addr
out dx,ax ; set display addr low
ret
xsetvpage ENDP
;****************************************************************************
PUBLIC xplot
xplot PROC x:word, y:word, color:byte, vpage:word
push es
push di
mov ax,0a000h
mov es,ax ; point to vga memory segment
mov bx,vpage ; get page #
and bx,00000011b ; make sure page # is in range 0->3
shl bx,1 ; scale bx
mov di,cs:pages[bx] ; get page offset
mov bx,y ; get y coord
shl bx,1 ; y=y*2
add di,cs:rows[bx] ; get offset to start of line
mov bx,x ; get x
mov cx,bx ; copy to extract plane # from
shr bx,2 ; x offset (bytes) = x/4
add di,bx ; offset = width*y + x/4
mov ax,map_mask_plane1 ; map mask & plane select register
and cl,plane_bits ; get plane bits
shl ah,cl ; get plane select value
out_16 sc_index,ax ; select plane
mov al,byte ptr color ; get pixel color
mov byte ptr es:[di],al ; draw pixel
pop di
pop es
ret
xplot ENDP
;****************************************************************************
PUBLIC xget
xget PROC x:word, y:word, vpage:word
push es
push di
mov ax,0a000h
mov es,ax ; point to vga memory segment
mov bx,vpage ; get page #
and bx,00000011b ; make sure page # is in range 0->3
shl bx,1 ; scale bx
mov di,cs:pages[bx] ; get page offset
mov bx,y ; get y coord
shl bx,1 ; y=y*2
add di,cs:rows[bx] ; get offset to start of line
mov bx,x ; get x
mov cx,bx ; copy to extract plane # from
shr bx,2 ; x offset (bytes) = x/4
add di,bx ; offset = width*y + x/4
mov ax,read_map ; read map register
and cl,plane_bits ; get plane bits
out_16 gc_index,ax ; select plane
mov al,byte ptr es:[di] ; get pixel color
pop di
pop es
ret
xget ENDP
;****************************************************************************
bmpx dw ?
bmpy dw ?
skew dw ?
offi dw ?
paste dw ?
;****************************************************************************
PUBLIC ximageput ; for now ignores remaining 4 or less pixels
ximageput PROC bitmap:dword, x:word, y:word, vpage:word
push ds
push es
push si
push di
mov ds,offset bitmap+2 ; get bitmap data segment
mov si,offset bitmap ; get bitmap data offset
mov ax,0A000h ;
mov es,ax ; point to vga memory segment
mov bx,vpage ; get page #
and bx,00000011b ; make sure page # is in range 0->3
shl bx,1 ; scale bx
mov di,cs:pages[bx] ; get page offset
mov bx,y ; get y coord
shl bx,1 ; y=y*2
add di,cs:rows[bx] ; add offset to start of line
mov bx,x ; get x
mov cx,bx ; copy to extract plane # from
xor ch,ch ; ignore high word
shr bx,2 ; x offset (bytes) = x/4
add di,bx ; add x offset
mov offi,di ; keep di in var offi for later use
xor bx,bx ; clear bx
lodsw ; get bitmap width
mov skew,ax ; keep it in var skew
and skew,00000011b ; skew now has # of remaining pixels
shr ax,2 ; ax=ax/4
mov bmpx,ax ; bmpx=bitmap width/4
lodsw ; get bitmap height
mov bmpy,ax ; keep it in var bmpy
add bitmap,4 ; point to bitmap data
mov paste,0 ; clear paste var
xdbmp1:
inc ch ; ch will be used as a counter (4)
mov ax,map_mask_plane1 ; map mask & plane select register
and cl,plane_bits ; get plane bits
shl ah,cl ; get plane select value
out_16 sc_index,ax ; select plane
push cx
call xdb ; draw in it
pop cx
cmp ch,4 ; all planes done ?
je xdbmp3 ; if so, end
cmp paste,0 ; are we in a new video ram offset ?
je xdbmp2 ; if not, continue
add di,1 ; if so, inc destination index
xdbmp2:
add cl,1 ; next plane(cl will have plane bits)
cmp cl,4 ; inc plane
jne xdbmp1 ;
xor cl,cl
mov paste,1
add di,1
jmp xdbmp1
xdbmp3:
pop di
pop si
pop es
pop ds
ret
xdb PROC NEAR
mov cx,bmpy ; loop bmpy times
xdb1:
push cx
mov cx,bmpx ; loop bmpx times
xdb2:
movsb ; plot pixel (and advance 1 pixel)
add si,3 ; advance 3 pixels
loop xdb2
pop cx
add si,skew ; step over bitmap skew times
add di,scr_width ; goto next line
sub di,bmpx
loop xdb1
mov di,offi ; goto begining vram offset
inc bx
mov si,offset bitmap ; point to bitmap data
add si,bx ; plus bx
ret
xdb ENDP
ximageput ENDP
;****************************************************************************
PUBLIC ximageadd ; for now ignores remaining 4 or less pixels
ximageadd PROC bitmap:dword, x:word, y:word, vpage:word
push ds
push es
push si
push di
mov ds,offset bitmap+2 ; get bitmap data segment
mov si,offset bitmap ; get bitmap data offset
mov ax,0A000h ;
mov es,ax ; point to vga memory segment
mov bx,vpage ; get page #
and bx,00000011b ; make sure page # is in range 0->3
shl bx,1 ; scale bx
mov di,cs:pages[bx] ; get page offset
mov bx,y ; get y coord
shl bx,1 ; y=y*2
add di,cs:rows[bx] ; add offset to start of line
mov bx,x ; get x
mov cx,bx ; copy to extract plane # from
xor ch,ch ; ignore high word
shr bx,2 ; x offset (bytes) = x/4
add di,bx ; add x offset
mov offi,di ; keep di in var offi for later use
xor bx,bx ; clear bx
lodsw ; get bitmap width
mov skew,ax ; keep it in var skew
and skew,00000011b ; skew now has # of remaining pixels
shr ax,2 ; ax=ax/4
mov bmpx,ax ; bmpx=bitmap width/4
lodsw ; get bitmap height
mov bmpy,ax ; keep it in var bmpy
add bitmap,4 ; point to bitmap data
mov paste,0 ; clear paste var
xia1:
inc ch ; ch will be used as a counter (4)
mov ax,map_mask_plane1 ; map mask & plane select register
and cl,plane_bits ; get plane bits
shl ah,cl ; get plane select value
out_16 sc_index,ax ; select plane
mov al,read_map ; read map register
mov ah,cl
out_16 gc_index,ax ; select plane
push cx
call xadd ; draw in it
pop cx
cmp ch,4 ; all planes done ?
je xia3 ; if so, end
cmp paste,0 ; are we in a new video ram offset ?
je xia2 ; if not, continue
add di,1 ; if so, inc destination index
xia2:
add cl,1 ; next plane(cl will have plane bits)
cmp cl,4 ; inc plane
jne xia1 ;
xor cl,cl
mov paste,1
add di,1
jmp xia1
xia3:
pop di
pop si
pop es
pop ds
ret
xadd PROC NEAR
mov cx,bmpy ; loop bmpy times
xadd1:
push cx
mov cx,bmpx ; loop bmpx times
xadd2:
mov al,es:[di]
add al,ds:[si]
mov es:[di],al ; plot pixel
add si,4 ; advance 3 pixels
add di,1
loop xadd2
pop cx
add si,skew ; step over bitmap skew times
add di,scr_width ; goto next line
sub di,bmpx
loop xadd1
mov di,offi ; goto begining vram offset
inc bx
mov si,offset bitmap ; point to bitmap data
add si,bx ; plus bx
ret
xadd ENDP
ximageadd ENDP
;****************************************************************************
PUBLIC xresize
xresize PROC x:word, y:word
mov ax,x ; get new screen width
mov vxmax,ax ; save new screen width
shr ax,2 ; bytes = pixels / 4
mov scr_width, ax ; save width in bytes
mov ax,y ; get new screen height
mov vymax,ax ; save new screen height
mov cx,800
mov bx,offset rows ; point to rows table
xor ax,ax ; clear ax
xr1:
mov cs:[bx],ax ; put row offset in table
add ax,scr_width ; get next row offset
add bx,2 ; advance pointer
loop xr1 ; loop until i'ts done
mov bx,8 ; bx = 8 pixels wide
mov ax,x ; ax = number of pixels per row
div bl ; al = number of character columms
xchg ah,al ; ah = number of character columms
mov al,13h ; CRTC offset register number
out_16 crtc_index,ax
ret
xresize ENDP
;****************************************************************************
PUBLIC xpanscr
xpanscr PROC x:word, y:word
mov dx,3dah ; video status port
in al,dx ; reset flip-flop
mov dx,3c0h ; attribute controller port
mov al,13h or 20h ; horiz pel pan reg number OR 0x20
out dx,al ; write attribute controller address reg
mov al,byte ptr x ; get pixel x coordinate
and al,3 ; value for horiz pel pan reg
shl al,1
out dx,al ; write horiz pel pan reg
mov bx,y ; get pixel y coordinate
xor dx,dx
mov ax,x ; get pixel x coordinate
div vxmax
add bx,ax
mov vymin,bx ; save new virtual minimum x
shl bx,1 ; scale bx
mov bx,cs:rows[bx] ; get row offset from table
mov vxmin,dx ; save new virtual minimum x
mov ax,dx
shr ax,2 ; divide by 4 (for X-mode)
add bx,ax ; save it for later use
mov dx,03d4h ; vga crt controller
mov al,0ch ; start address high reg number
mov ah,bh ; get start address high
out dx,ax ; write start address high
mov al,0dh ; start address low reg number
mov ah,bl ; get start address low
out dx,ax ; write start address low
ret
xpanscr ENDP
;****************************************************************************
PUBLIC xsplit
xsplit PROC n:word
mov dx,3d4h
mov ax,n
mov vymax,ax
mov bh,ah
mov bl,bh
and bx,0201h
mov cl,4
shl bx,cl
shl bh,1
mov ah,al
mov al,18h
out dx,ax
mov al,7
out dx,ax
inc dx
in al,dx
dec dx
mov ah,al
and ah,11101111b
or ah,bl
mov al,7
out dx,ax
mov al,9
out dx,al
inc dx
in al,dx
dec dx
mov ah,al
and ah,10111111b
or ah,bh
mov al,9
out dx,ax
ret
xsplit ENDP
;****************************************************************************
PUBLIC xlineputcy
xlineputcy PROC pointer:dword, ya:word, x:word, y:word, vpage:word
push ds
push es
push si
push di
mov ax,0a000h
mov es,ax
mov bx,vpage ; get page #
and bx,00000011b ; make sure page # is in range 0->3
shl bx,1 ; scale bx
mov di,cs:pages[bx] ; get page offset
mov bx,y ; get y coord
shl bx,1 ; y=y*2
add di,cs:rows[bx] ; get offset to start of line
mov bx,x ; get x
mov cx,bx ; copy to extract plane # from
shr bx,2 ; x offset (bytes) = x/4
add di,bx ; offset = width*y + x/4
mov ax,map_mask_plane1 ; map mask & plane select register
and cl,plane_bits ; get plane bits
shl ah,cl ; get plane select value
out_16 sc_index,ax ; select plane
mov si,offset pointer
mov ds,offset pointer+2
xor bx,bx
xor dx,dx
xor cx,cx
plcy1:
mov cl,byte ptr ds:[si]
add bx,cx
mov al,byte ptr ds:[si+1]
plcy2:
mov byte ptr es:[di],al
add di,scr_width
loop plcy2
add si,2
add dx,2
cmp bx,ya
jl plcy1
mov ax,dx
pop di
pop si
pop es
pop ds
ret
xlineputcy ENDP
;****************************************************************************
PUBLIC xblock
xblock PROC x1:word, y1:word, count:word, y2:word, color:byte, vpage:word
push es
push di
mov ax,0a000h
mov es,ax
mov bx,vpage ; get page #
and bx,00000011b ; make sure page # is in range 0->3
shl bx,1 ; scale bx
mov di,cs:pages[bx] ; get page offset
mov bx,y1 ; get y coord
shl bx,1 ; y=y*2
add di,cs:rows[bx] ; get offset to start of line
mov bx,x1 ; get x
shr bx,2 ; x offset (bytes) = x/4
add di,bx ; offset = width*y + x/4
mov dx,003c4h ; update all 4 bit-planes at the same time
mov ax,00f02h
out dx,ax
mov al,color
mov cx,count
xb1:
push di
push cx
mov cx,y2
sub cx,y1
xb2:
mov byte ptr es:[di],al
add di,scr_width
loop xb2
pop cx
pop di
inc di
loop xb1
pop di
pop es
ret
xblock ENDP
;****************************************************************************
PUBLIC xvwait
xvwait PROC
mov dx,03DAh
xvw1:
in al,dx
test al,8
jnz xvw1 ; wait Until out of vertical retrace
xvw2:
in al,dx
test al,8
jz xvw2 ; wait Until inside vertical retrace
ret
xvwait ENDP
;****************************************************************************
PUBLIC xhwait
xhwait PROC
mov dx,03DAh
xhw1:
in al,dx
test al,1
jnz xhw1 ; wait Until out of vertical retrace
xhw2:
in al,dx
test al,1
jz xhw1 ; wait Until inside vertical retrace
ret
xhwait ENDP
;******************************************************************************
PUBLIC xsetborder
xsetborder PROC color:byte
push ax
push dx
cli
mov dx,3dah
in al,dx
mov dx,3c0h
mov al,11h+32
out dx,al
mov al,color
out dx,al
sti
pop dx
pop ax
ret
xsetborder ENDP
;******************************************************************************
PUBLIC xsetborder2
xsetborder2 PROC red:byte, green:byte, blue:byte
push ax
push dx
cli
mov dx,3c8h
mov al,0
out dx,al
mov dx,3c9h
mov al,red
out dx,al
mov al,green
out dx,al
mov al,blue
out dx,al
sti
pop dx
pop ax
ret
xsetborder2 ENDP
;******************************************************************************
PUBLIC xscreenoff
xscreenoff PROC mode:byte
mov dx,3dah ; reset flip-flop
in al,dx
out_8 attrib_ctrl,0 ; disable screen
out_8 sc_index,1 ; vga sequencer, index 1
inc dx ; vga sequencer data port
in al,dx ; get previous settings
or al,00100000b ; set bit 5 (turn off screen)
out dx,al ; restore new settings
ret
xscreenoff ENDP
;******************************************************************************
PUBLIC xscreenon
xscreenon PROC mode:byte
mov dx,3dah ; reset flip-flop
in al,dx
out_8 attrib_ctrl,20h ; enable screen
out_8 sc_index,1 ; vga sequencer, index 1
inc dx ; vga sequencer data port
in al,dx ; get previous settings
and al,11011111b ; reset bit 5 (turn on screen)
out dx,al ; restore new settings
ret
xscreenon ENDP
;******************************************************************************
PUBLIC xsetpalette
xsetpalette PROC FAR pointer: dword
push ds
push si
cli
mov cx,256
mov ds,word ptr pointer+2
mov si,word ptr pointer
mov dx,03c8h
mov al,0
out dx,al
inc dx
sp1:
lodsb
out dx,al
lodsb
out dx,al
lodsb
out dx,al
loop sp1
sti
pop si
pop ds
ret
xsetpalette ENDP
;******************************************************************************
PUBLIC xgetpalette
xgetpalette PROC FAR firstreg:word, numregs:word, palette:dword
push es
push di
mov cx,numregs
jcxz xgp2
les di,palette
cld
mov dx,03C7h
mov ax,firstreg
out dx,al
mov dx,03C9h
xgp1:
in al,dx
shl al,2
stosb ; red
in al,dx
shl al,2
stosb ; green
in al,dx
shl al,2
stosb ; blue
loop xgp1
xgp2:
pop di
pop es
ret
xgetpalette ENDP
;******************************************************************************
PUBLIC xsetrgb
xsetrgb PROC FAR color:byte, red:byte, green:byte, blue:byte
cli
mov dx,03c8h
mov al,color
out dx,al
inc dx
mov al,red
out dx,al
mov al,green
out dx,al
mov al,blue
out dx,al
sti
ret
xsetrgb ENDP
;******************************************************************************
PUBLIC xtextmode
xtextmode PROC FAR mode:byte
mov ax,03h ; set text mode
int 10h
cmp mode,25 ; 50 lines mode ?
je no50
mov ax,1112h ; set font height to 8 pixels
xor bx,bx
int 10h
no50:
ret
xtextmode ENDP
;******************************************************************************
apage dw ?
;******************************************************************************
PUBLIC movewin
movewin PROC buffer1:dword, buffer2:dword, vpage:word
push ds
push si
push es
push di
mov ax,0a000h
mov es,ax
mov bx,vpage ; get page #
and bx,00000011b ; make sure page # is in range 0->3
shl bx,1 ; scale bx
mov ax,pages[bx]
add ax,9
mov apage,ax
lds si,buffer1
lfs bx,buffer2
mov dx,003c4h
mov ax,0102h
mw1:
push ax
mov di,apage ; get page offset
out dx,ax
mov cx,200
mw0:
push cx
mov cx,15
mw2:
mov eax,dword ptr ds:[si]
and eax,dword ptr fs:[bx]
mov dword ptr es:[di],eax
add si,4
add bx,4
add di,4
loop mw2
pop cx
add di,20
add si,20
add bx,20
loop mw0
mov ax,ds
add ax,405
mov ds,ax
mov ax,fs
add ax,405
mov fs,ax
pop ax
shl ah,1
cmp ah,8
jbe mw1
pop di
pop es
pop si
pop ds
ret
movewin ENDP
END